#include <opencv2/highgui.hpp>
#include <opencv2/dnn/dnn.hpp>
#include <gflags/gflags.h>
#include <fstream>
#include <vector>
#include <string>
#include "../../log/log.h"

// DEFINE_bool     (verbose, false, "冗长打印");
DEFINE_string(input,  "imge01.jpg",
                       "要输入模型的图片");
DEFINE_string(model,  "bvlc_googlenet.caffemodel",
                       "要读入的模型");
DEFINE_string(config, "bvlc_googlenet.prototxt",
                       "要读入模型的配置文件");
DEFINE_string(classes,"classification_classes_ILSVRC2012.txt",
                       "要读入的classes信息文件");

int main(int argc, char* argv[])
{
    gflags::SetUsageMessage("用opencv调取caffe平台的googlenet模型");
    gflags::SetVersionString("0.1");
    gflags::ParseCommandLineFlags(&argc, &argv, true);
    
    // 读取classes文件
    std::ifstream ifs(FLAGS_classes.c_str());
    std::vector<std::string> classes;
    if(!ifs.is_open()) {
        LOG("文件读取失败。");
        return -1;
    } else {
        std::string line;
        while (std::getline(ifs, line))
        {
            classes.push_back(line);
        }
    }

    // 读取预训练模型
    cv::dnn::Net net = cv::dnn::readNet(FLAGS_model, FLAGS_config, "abc");// FLAGS_framework);

    // 生成blob
    cv::Mat matInput = cv::imread(FLAGS_input);
    cv::Mat blob;
    float scale = 1.0;
    int inpWidth = 224, inpHeight = 224;
    cv::Scalar mean = {104,117,123,0}; // 每个通道分别减去mean里的值
    bool swapRB = false, crop = false; // cropped裁剪
    cv::dnn::blobFromImage(matInput, blob, scale, cv::Size(inpWidth, inpHeight), mean, swapRB, crop);
    
    // 计时
    cv::TickMeter timeRecorder;
    timeRecorder.start();
    
    // 输入网络并运行获得网络输出
    net.setInput(blob);
    cv::Mat prob = net.forward();

    // 解析网络输出
    double confidence;
    cv::Point classIdPoint;
    cv::minMaxLoc(prob.reshape(1, 1), 0, &confidence, 0, &classIdPoint);
    int classId = classIdPoint.x;
    timeRecorder.stop();

    // 打印结果
    LOG("time of 1 round: %.3f ms", timeRecorder.getTimeMilli());
    LOG("%s: %.3f", classes[classId].c_str(), confidence);
    
    return 0;
}